package tehUtils;

import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;

import net.minecraft.src.AxisAlignedBB;

public class BlockFinder {

	private BlockFinder() {}
	
	public static Set getBlocksInArea(AxisAlignedBB searchArea) {
		return new BlockSearch(searchArea).search();
	}
	
	public static Set getBlocksInArea(AxisAlignedBB searchArea, int blockID) {
		return new BlockSearch(searchArea, blockID).search();
	}
	
	public static Set getBlocksInArea(AxisAlignedBB searchArea, int blockID, int metadata) {
		return new BlockSearch(searchArea, blockID, metadata).search();
	}
	
	public static Set getBlocksInArea(AxisAlignedBB searchArea, int[] blockIDs) {
		Set output = new HashSet();
		for (int i = 0; i < blockIDs.length; i++)
			output.addAll(new BlockSearch(searchArea, blockIDs[i]).search());
		return output;
	}
	
	public static Set getBlocksInArea(AxisAlignedBB searchArea, int[] blockIDs, int metadata) {
		Set output = new HashSet();
		for (int i = 0; i < blockIDs.length; i++)
			output.addAll(new BlockSearch(searchArea, blockIDs[i], metadata).search());
		return output;
	}
	
	public static Set getBlocksInArea(AxisAlignedBB searchArea, int[] blockIDs, int[] metadatas) {
		Set output = new HashSet();
		for (int i = 0; i < blockIDs.length; i++)
			for (int j = 0; j < metadatas.length; j++)
			output.addAll(new BlockSearch(searchArea, blockIDs[i], metadatas[j]).search());
		return output;
	}
	
	public static Set getBlocksInArea(AxisAlignedBB searchArea, int blockID, int[] metadatas) {
		Set output = new HashSet();
		for (int i = 0; i < metadatas.length; i++)
			output.addAll(new BlockSearch(searchArea, blockID, metadatas[i]).search());
		return output;
	}
	
	private static double[] getCenter(AxisAlignedBB searchArea) {
		return new double[] {
				(searchArea.maxX + searchArea.minX) * 0.5,
				(searchArea.maxY + searchArea.minY) * 0.5,
				(searchArea.maxZ + searchArea.minZ) * 0.5,
			};
	}
	
	public static BlockInstance getClosestBlock(Set blocks, double[] center) {
		double closestDistance = 999999999.9d;
		BlockInstance closestBlock = null;
		for (Iterator iterator = blocks.iterator(); iterator.hasNext();) {
			BlockInstance block = (BlockInstance) iterator.next();
			double distance = Math.pow(block.posX - center[0], 2) + Math.pow(block.posY - center[1], 2) + Math.pow(block.posZ - center[2], 2);
			if (distance < closestDistance) {
				closestDistance = distance;
				closestBlock = block;
			}
		}
		return closestBlock;
	}
	
	public static BlockInstance getClosestBlock(AxisAlignedBB searchArea, int blockID) {
		Set blocks = getBlocksInArea(searchArea, blockID);
		return getClosestBlock(blocks, getCenter(searchArea));
	}
	
	public static BlockInstance getClosestBlock(AxisAlignedBB searchArea, int blockID, int metadata) {
		Set blocks = getBlocksInArea(searchArea, blockID, metadata);
		return getClosestBlock(blocks, getCenter(searchArea));
	}
	
	public static BlockInstance getClosestBlock(AxisAlignedBB searchArea, int blockID, int[] metadatas) {
		Set blocks = getBlocksInArea(searchArea, blockID, metadatas);
		return getClosestBlock(blocks, getCenter(searchArea));
	}
	
	public static BlockInstance getClosestBlock(AxisAlignedBB searchArea, int[] blockIDs) {
		Set blocks = getBlocksInArea(searchArea, blockIDs);
		return getClosestBlock(blocks, getCenter(searchArea));
	}
	
	public static BlockInstance getClosestBlock(AxisAlignedBB searchArea, int[] blockIDs, int metadata) {
		Set blocks = getBlocksInArea(searchArea, blockIDs, metadata);
		return getClosestBlock(blocks, getCenter(searchArea));
	}
	
	public static BlockInstance getClosestBlock(AxisAlignedBB searchArea, int[] blockIDs, int[] metadatas) {
		Set blocks = getBlocksInArea(searchArea, blockIDs, metadatas);
		return getClosestBlock(blocks, getCenter(searchArea));
	}
	
	
}
